import pygame
import random
import math

class Particle:
    def __init__(self, x, y, color=(255, 192, 203), style="normal", trail_length=0):
        """初始化一个粒子
        
        Args:
            x (float): 初始x坐标
            y (float): 初始y坐标
            color (tuple): RGB颜色值，默认为粉色
            style (str): 粒子样式，可选值："normal", "star", "heart"
            trail_length (int): 粒子轨迹长度，0表示无轨迹
        """
        self.x = x
        self.y = y
        self.color = color
        # 随机生成粒子的初始速度和方向
        angle = random.uniform(0, 2 * math.pi)
        speed = random.uniform(1, 3)
        self.vx = math.cos(angle) * speed
        self.vy = math.sin(angle) * speed
        # 粒子的生命周期
        self.lifetime = 100
        self.age = 0
        # 粒子样式和大小
        self.style = style
        self.size = random.randint(3, 6)
        self.original_size = self.size
        self.rotation = random.uniform(0, 360)
        self.spin_speed = random.uniform(-5, 5)
        
        # 粒子轨迹
        self.trail_length = trail_length
        self.positions = [(x, y)] * trail_length if trail_length > 0 else []
        
        # 特效参数
        self.flash_speed = random.uniform(0.05, 0.15)
        self.flash_offset = random.uniform(0, math.pi * 2)
        self.pulse_speed = random.uniform(0.05, 0.15)
        self.pulse_offset = random.uniform(0, math.pi * 2)
        
    def update(self):
        """更新粒子的位置和状态"""
        # 更新位置
        self.x += self.vx
        self.y += self.vy
        # 添加重力效果
        self.vy += 0.1
        
        # 更新轨迹
        if self.trail_length > 0:
            self.positions.insert(0, (self.x, self.y))
            if len(self.positions) > self.trail_length:
                self.positions.pop()
        
        # 闪烁和脉动效果
        flash_factor = 0.3 * math.sin(self.age * self.flash_speed + self.flash_offset) + 0.7
        pulse_factor = 0.3 * math.sin(self.age * self.pulse_speed + self.pulse_offset) + 0.7
        self.size = self.original_size * pulse_factor
        
        # 旋转更新
        self.rotation += self.spin_speed
        
        # 增加年龄
        self.age += 1
        
    def is_alive(self):
        """检查粒子是否还存活"""
        return self.age < self.lifetime
    
    def draw(self, screen):
        """在屏幕上绘制粒子
        
        Args:
            screen: pygame的屏幕对象
        """
        # 绘制轨迹
        if self.trail_length > 0 and len(self.positions) > 1:
            for i in range(len(self.positions) - 1):
                # 计算轨迹段的透明度
                alpha = int(255 * (1 - i / len(self.positions)) * 0.3)
                # 绘制轨迹线段
                pygame.draw.line(screen, (*self.color, alpha),
                               self.positions[i], self.positions[i + 1], 2)
        
        # 根据粒子的年龄计算透明度
        alpha = int(255 * (1 - self.age / self.lifetime))
        
        # 创建一个临时surface来支持透明度
        size_with_glow = int(self.size * 3)  # 为光晕效果预留空间
        surf = pygame.Surface((size_with_glow * 2, size_with_glow * 2), pygame.SRCALPHA)
        center = (size_with_glow, size_with_glow)
        
        if self.style == "normal":
            # 绘制光晕效果
            for glow_size in [self.size * 2, self.size * 1.5, self.size]:
                glow_alpha = int(alpha * (glow_size / (self.size * 2)))
                pygame.draw.circle(surf, (*self.color, glow_alpha), 
                                 center, glow_size)
                
        elif self.style == "star":
            # 绘制星形光晕
            self._draw_star(surf, center[0], center[1], self.size * 2, int(alpha * 0.3))
            self._draw_star(surf, center[0], center[1], self.size * 1.5, int(alpha * 0.5))
            self._draw_star(surf, center[0], center[1], self.size, alpha)
            
        elif self.style == "heart":
            # 绘制爱心光晕
            self._draw_heart(surf, center[0], center[1], self.size * 2, int(alpha * 0.3))
            self._draw_heart(surf, center[0], center[1], self.size * 1.5, int(alpha * 0.5))
            self._draw_heart(surf, center[0], center[1], self.size, alpha)
            
        # 旋转surface
        rotated_surf = pygame.transform.rotate(surf, self.rotation)
        # 获取旋转后的矩形以正确定位
        rect = rotated_surf.get_rect(center=(self.x, self.y))
        # 将粒子绘制到主屏幕
        screen.blit(rotated_surf, rect)
        
    def _draw_star(self, surface, x, y, size, alpha):
        """绘制星形"""
        points = []
        for i in range(10):
            angle = math.pi * 2 * i / 10 - math.pi / 2
            r = size if i % 2 == 0 else size * 0.4
            points.append((
                x + math.cos(angle) * r,
                y + math.sin(angle) * r
            ))
        pygame.draw.polygon(surface, (*self.color, alpha), points)
        
    def _draw_heart(self, surface, x, y, size, alpha):
        """绘制小爱心"""
        # 使用三个圆形组合成爱心形状
        r = size * 0.5
        # 绘制两个圆形作为爱心的上部
        pygame.draw.circle(surface, (*self.color, alpha),
                         (x - r/2, y - r/2), r)
        pygame.draw.circle(surface, (*self.color, alpha),
                         (x + r/2, y - r/2), r)
        # 绘制一个三角形作为爱心的下部
        points = [
            (x - r, y - r/2),
            (x + r, y - r/2),
            (x, y + r)
        ]
        pygame.draw.polygon(surface, (*self.color, alpha), points)

class ParticleSystem:
    def __init__(self):
        """初始化粒子系统"""
        self.particles = []
        self.color_mode = "pink"  # 默认为粉色模式
        self.particle_style = "normal"  # 默认粒子样式
        
    def emit(self, x, y, count=10, trail_length=0, spread=1.0):
        """在指定位置发射粒子
        
        Args:
            x (float): 发射位置的x坐标
            y (float): 发射位置的y坐标
            count (int): 发射的粒子数量
            trail_length (int): 粒子轨迹长度
            spread (float): 粒子扩散程度，1.0为正常扩散
        """
        for _ in range(count):
            color = self._get_color()
            particle = Particle(
                x + random.uniform(-5, 5) * spread,
                y + random.uniform(-5, 5) * spread,
                color,
                self.particle_style,
                trail_length
            )
            # 根据扩散程度调整速度
            particle.vx *= spread
            particle.vy *= spread
            self.particles.append(particle)
            
    def _get_color(self):
        """根据当前颜色模式获取颜色"""
        base_color = self._get_base_color()
        # 添加随机微调以增加色彩变化
        variation = 20  # 颜色变化范围
        return tuple(min(255, max(0, c + random.randint(-variation, variation)))
                    for c in base_color)
    
    def _get_base_color(self):
        """获取基础颜色"""
        if self.color_mode == "pink":
            # 使用更丰富的粉色渐变
            pink_variants = [
                (255, 192, 203),  # 粉红
                (255, 182, 193),  # 浅粉红
                (255, 105, 180),  # 热粉红
                (255, 20, 147),   # 深粉红
                (255, 160, 122)   # 浅鲑鱼色
            ]
            return random.choice(pink_variants)
            
        elif self.color_mode == "rainbow":
            # 使用更平滑的彩虹色过渡
            hue = (pygame.time.get_ticks() / 50 + random.uniform(0, 30)) % 360
            # HSV转RGB
            c = 1
            x = c * (1 - abs((hue / 60) % 2 - 1))
            m = 1 - c
            
            if hue < 60:
                r, g, b = c, x, 0
            elif hue < 120:
                r, g, b = x, c, 0
            elif hue < 180:
                r, g, b = 0, c, x
            elif hue < 240:
                r, g, b = 0, x, c
            elif hue < 300:
                r, g, b = x, 0, c
            else:
                r, g, b = c, 0, x
                
            return (
                int((r + m) * 255),
                int((g + m) * 255),
                int((b + m) * 255)
            )
            
        elif self.color_mode == "gold":
            # 使用更丰富的金色渐变
            gold_variants = [
                (255, 215, 0),    # 金色
                (255, 223, 0),    # 亮金色
                (238, 232, 170),  # 浅金色
                (255, 198, 0),    # 橙金色
                (255, 185, 15)    # 深金色
            ]
            return random.choice(gold_variants)
            
        return (255, 192, 203)  # 默认粉色
            
    def set_color_mode(self, mode):
        """设置颜色模式
        
        Args:
            mode (str): 颜色模式，可选值："pink", "rainbow", "gold"
        """
        if mode in ["pink", "rainbow", "gold"]:
            self.color_mode = mode
            # 当切换颜色模式时，为现有粒子添加过渡效果
            for particle in self.particles:
                particle.color = self._get_color()
        
    def set_particle_style(self, style):
        """设置粒子样式
        
        Args:
            style (str): 粒子样式，可选值："normal", "star", "heart"
        """
        self.particle_style = style
            
    def update(self):
        """更新所有粒子的状态"""
        # 使用列表推导式保留仍然存活的粒子
        self.particles = [p for p in self.particles if p.is_alive()]
        # 更新所有存活粒子的状态
        for particle in self.particles:
            particle.update()
            
    def draw(self, screen):
        """绘制所有粒子
        
        Args:
            screen: pygame的屏幕对象
        """
        for particle in self.particles:
            particle.draw(screen)